package team.cdlzz.controller;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import team.cdlzz.dao.UserMapper;
import team.cdlzz.model.pojo.User;
import team.cdlzz.model.servicePojo.Message;
import team.cdlzz.model.servicePojo.SocketUser;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint(value = "/socket/{name}")
@Component
@Controller
public class WebSocketController {

    public static UserMapper userMapper;

    //使用线程安全对象进行操作
    private static ConcurrentHashMap<Session,SocketUser> sessionMapUser = new ConcurrentHashMap();
    private static ArrayList<SocketUser> userList = new ArrayList<>();
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    @OnOpen
    public void onOpen(Session session,@PathParam("name") String name) {
        onlineCount.incrementAndGet(); // 在线数加1
        System.out.println(name);
        User u = userMapper.UserEmailExist(name);
        if (u!=null){   //如果验证成功,加入聊天室
            SocketUser user = addUser(session,u); //添加到聊天室队列---暂时不添加进入用户列表
            SendLoginInit(session,user);     //返回初始化数据
            SendAddMessage(user);       //加入用户队列,发送用户加入
        }
    }

    @OnClose
    public void onClose  (Session session) {
        SocketUser user = SessionGetUser(session);
        System.out.println(user.toString());
        UserClose(session,user);//在列表中删除用户
        SendClose(user);
    }


    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println(message);
        Message m = JSONObject.parseObject(message, Message.class);

        SocketUser user = sessionMapUser.get(session);
        System.out.println("服务端收到客户端"+user.getUsername()+"的消息:"+ message);
        ConcurrentHashMap.KeySetView<Session, SocketUser> sessions = sessionMapUser.keySet();
        for (Session key : sessions) {
            sendMessage(m,key);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }


    /**
     * 发送单体消息
     * @param message
     * @param toSession
     */
    private void sendMessage(Message message, Session toSession) {
        try {
            toSession.getBasicRemote().sendText(JSONObject.toJSONString(message));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 发送群体消息
     * @param message
     */
    private void SendMessageAllUser(Message message){
        ConcurrentHashMap.KeySetView<Session, SocketUser> sessions = sessionMapUser.keySet();
        for (Session session : sessions){
            sendMessage(message,session);
        }
    }


    /**
     * 数据添加---加入用户
     *
     */
    private SocketUser addUser(Session session,User u){
        SocketUser user = new SocketUser(u);
        sessionMapUser.put(session,user);
        return user;
    }


    /**
     * 发送初始化数据
     * @param session
     * @param user
     */
    private void SendLoginInit(Session session , SocketUser user){
        Message message = Message.loginMessage(user,userList);
        System.out.println(user.getUsername()+"--加入聊天室 ===="+"，当前在线人数为："+ onlineCount.get());
        System.out.println(JSONObject.toJSONString(message));
        sendMessage(message,session);
    }


    /**
     * 用户加入队列 推送加入频道的消息
     * @param user
     */
    private void SendAddMessage(SocketUser user){
        Message message = new Message(user,user.getUsername()+"加入了聊天室",1,null);
        userList.add(user);
        SendMessageAllUser(message);
    }


    private void UserClose(Session session,SocketUser user){
        onlineCount.decrementAndGet(); // 在线数减1
        sessionMapUser.remove(session);
        userList.remove(user);
    }
    private void SendClose(SocketUser user){
        System.out.println("有一连接关闭："+user.getUsername()+ " 当前在线人数为："+onlineCount.get());
        Message message = new Message(user, user.getUsername()+" -- 退出房间",2,null);
        SendMessageAllUser(message);
    }


    private SocketUser SessionGetUser(Session session){
        return sessionMapUser.get(session);
    }
}